// 
// Copyright 2010 Classpath Pty Ltd <opensource@classpath.com.au>
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 

using migrations
using sql

**
** An example `migrations::MigrationMain` configured to use the standard 'fantest' database (see `sql::pod-doc` for details).
**
class ExampleMain : MigrationMain {

    **
    ** Provides a MySql adapter for using with the configured MySQL `sys::SqlService` above.
    **
    override Adapter adapter := MySqlAdapter()

    **
    ** Registers the known migrations which can be performed.
    **
    override Migration[] migrations := [ExampleMigration1(), ExampleMigration2(), ExampleMigration3()]


    new make() {
        uri = "jdbc:mysql://localhost/fantom"
        username = "fantom"
        password = "fantom"
    }

}

**
** An example `migrations::Migration` that shows a simple create/drop table with some columns.
**
class ExampleMigration1 : Migration {

    **
    ** The `sys::Version` being migrated from.
    **
    override Version from := Version.defVal

    **
    ** The `sys::Version` being migrated to.
    **
    override Version to := Version("1")

    **
    ** Defines the upwards steps for this `migrations::Migration`.
    **
    override Void up() {
        createTable("location") {
            createColumn("location_id", integer) { autoIncrement; comment("Locations ID"); primaryKey }
            createColumn("location_name", varchar(255)) { comment("Locations Name"); notNull; unique }
        }
        createTable("person") {
            createColumn("person_id", integer) { autoIncrement; comment("Persons ID"); primaryKey }
            createColumn("location_id", integer) { notNull; references("location", "location_id") }
            createColumn("given_name", varchar(64)) { notNull }
            createColumn("family_name", varchar(64)) { notNull }
            unique("uq_names", ["family_name", "given_name"])
        }
        createTable("phone") {
            createColumn("phone_id", integer) { autoIncrement; comment("Resumes ID"); primaryKey }
            createColumn("given_name", varchar(64)) { notNull }
            createColumn("family_name", varchar(64)) { notNull }
            createColumn("phone_number", varchar(16)) { notNull }
            unique("uq_names", ["family_name", "given_name"])
            foreignKey("fk_given_name", ["given_name", "family_name"], references("person", ["given_name", "family_name"]))
        }
    }

    **
    ** Defines the downwards steps for this `migrations::Migration`.
    **
    override Void down() {
        dropTable("phone")
        dropTable("person")
        dropTable("location")
    }

}


**
** An example `migrations::Migration` that shows a simple alter table with some create/drop of columns.
**
class ExampleMigration2 : Migration {

    **
    ** The `sys::Version` being migrated from.
    **
    override Version from := Version("1")

    **
    ** The `sys::Version` being migrated to.
    **
    override Version to := Version("2")

    **
    ** Defines the upwards steps for this `migrations::Migration`.
    **
    override Void up() {
        alterTable("location") {
            createColumn("latitude", decimal(3, 3)) { comment("Locations Latitude") }
            createColumn("longitude", decimal(3, 3)) { comment("Locations Longitude") }
            createColumn("last_updated", timestamp) { defaultValue("NOW()") }
            index("idx_last_updated", ["last_updated"])
        }
        executeSql("UPDATE location SET latitude = 0.0")
        executeSql("UPDATE location SET longitude = 0.0")
    }

    **
    ** Defines the downwards steps for this `migrations::Migration`.
    **
    override Void down() {
        alterTable("location") {
            dropColumn("latitude")
            dropColumn("longitude")
        }
    }

}


**
** An example `migrations::Migration` that shows a simple alter table with some table options.
**
class ExampleMigration3 : Migration {

    **
    ** The `sys::Version` being migrated from.
    **
    override Version from := Version("2")

    **
    ** The `sys::Version` being migrated to.
    **
    override Version to := Version("3")

    **
    ** Defines the upwards steps for this `migrations::Migration`.
    **
    override Void up() {
        createTable("coordinate") {
            createColumn("latitude", decimal(3, 3)) { comment("Coordinates Latitude"); notNull }
            createColumn("longitude", decimal(3, 3)) { comment("Coordinates Longitude"); notNull }
            createColumn("name", varchar(255)) { comment("Coordinates Name"); notNull }
            createColumn("description", varchar(255)) { comment("Coordinates Description"); notNull }
            check("ck_latitude", "latitiude >= -90 and latitude <= 90")
            check("ck_longitude", "longitude >= -180 and longitude <= 180")
            index("idx_name", ["name"])
            primaryKey("pk_coordinate", ["latitude", "longitude"])
            unique("uq_name", ["name", "description"])
        }
        alterTable("location") {
            dropIndex("idx_last_updated")
        }
    }

    **
    ** Defines the downwards steps for this `migrations::Migration`.
    **
    override Void down() {
        dropTable("coordinate")
    }

}


